<template>
  <div class="bg_box">
    <!-- 头部区域 start -->
    <div class="header">
      <span class="topTbas" @click="$router.push({ name: 'Home' })">首页</span>
      <span>MayiGenerator-表单生成器</span>
      <span class="topTbas" @click="$router.push({ name: 'PageGenerator' })"
        >页面生成器</span
      >
    </div>
    <div class="content">
      <!-- 左侧区域 -->
      <div class="left">
        <el-scrollbar class="left-scrollbar">
          <Vuedraggable
            class="components-draggable"
            :list="basicsList"
            :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
            :clone="cloneComponent"
            draggable=".components-item"
            :sort="false"
            @end="onEnd"
          >
            <span
              v-for="(item, index) in basicsList"
              :key="index"
              class="components-item"
              @click="addComponent(item)"
            >
              {{ item.label }}
            </span>
          </Vuedraggable>
        </el-scrollbar>
      </div>
      <!-- 中间区域 -->
      <div class="section">
        <div class="action-bar">
          <!-- <el-button icon="el-icon-video-play" type="text">
            运行
          </el-button>
          <el-button icon="el-icon-view" type="text">
            查看json
          </el-button>
          <el-button icon="el-icon-download" type="text">
            导出vue文件
          </el-button> -->
          <el-button
            class="copy-btn-main"
            icon="el-icon-document-copy"
            type="text"
            @click="oNcode"
          >
            查看代码
          </el-button>
          <el-button
            class="delete-btn"
            icon="el-icon-delete"
            type="text"
            @click="onEmpty"
          >
            清空
          </el-button>
        </div>
        <el-scrollbar class="center-scrollbar">
          <el-form
            ref="form"
            :model="form"
            :label-position="formConfig.labelPosition"
            :disabled="formConfig.disabled"
            :size="formConfig.size"
            :label-width="formConfig.labelWidth + 'px'"
            class="form"
            :rules="rules"
          >
            <Vuedraggable
              class="drawing-board"
              :list="drawingList"
              :animation="340"
              @start="onStart"
              group="componentsGroup"
              @end="onEnd"
            >
              <div
                @click="onFormItem(element, index)"
                v-for="(element, index) in drawingList"
                :key="index"
                class="drawing"
                :class="active === index ? 'active' : ''"
              >
                <div class="drawing_masking"></div>
                <div class="rightTop" :class="active === index ? 'active' : ''">
                  <div class="copy" @click.stop="onCopy(element, index)">
                    <i class="el-icon-document-copy"></i>
                  </div>
                  <div class="delete" @click.stop="onDelete(element, index)">
                    <i class="el-icon-delete"></i>
                  </div>
                </div>
                <el-form-item
                  :label="element.label"
                  :prop="index.modal"
                  :required="element.attributes.required"
                >
                  <DraggableItem :current-item="element"></DraggableItem>
                </el-form-item>
              </div>
            </Vuedraggable>
          </el-form>
          <div v-show="!drawingList.length" class="empty-info">
            从左侧拖入或点选组件进行表单设计
          </div>
        </el-scrollbar>
      </div>
      <!-- 右侧区域 -->
      <div class="right">
        <RightPanel
          :activeFormItem.sync="activeFormItem"
          :formConfig="formConfig"
        />
      </div>
    </div>
    <!-- 查看代码 -->
    <el-dialog title="代码" :visible.sync="dialogVisible" width="1000px">
      <Codemirror
        class="codemirror"
        :options="{
          mode: 'vue',
          extraKeys: { 'Ctrl-Space': 'autocomplete' }
        }"
        :value="vueCode"
      ></Codemirror>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import * as vueCodemirrorLite from "vue-codemirror-lite";
require("codemirror/mode/javascript/javascript");
require("codemirror/mode/vue/vue");
require("codemirror/addon/hint/show-hint.js");
require("codemirror/addon/hint/show-hint.css");
require("codemirror/addon/hint/javascript-hint.js");
import Vuedraggable from "vuedraggable";
import DraggableItem from "./module/DraggableItem";
import { basicsList, formConfig } from "./config/formItemsConfig.js";
import { makeUpCss } from "../../utils/css";
import { makeUpJs } from "../../utils/js";
import {
  makeUpHtml,
  vueTemplate,
  vueScript,
  cssStyle
} from "../../utils/package";
import RightPanel from "./module/RightPanel";
import loadBeautifier from "@/utils/loadBeautifier";
import { beautifierConf } from "@/utils/index";
let beautifier;
export default {
  components: {
    Vuedraggable,
    DraggableItem,
    RightPanel,
    Codemirror: vueCodemirrorLite.codemirror
  },
  data() {
    return {
      vueCode: "",
      dialogVisible: false,
      form: {},
      formConfig,
      drawingList: [],
      formNmame: "form",
      basicsList,
      activeFormItem: {},
      active: -1,
      rules: {}
    };
  },
  created() {
    // let oldDta = localStorage.getItem("drawingList");
    // if (oldDta && oldDta !== null && oldDta !== null) {
    //   this.drawingList = JSON.parse(oldDta);
    // }
  },
  mounted() {
    loadBeautifier(btf => {
      beautifier = btf;
    });
  },
  watch: {
    drawingList: {
      handler(val) {
        // localStorage.setItem("drawingList", JSON.stringify(val));
      },
      deep: true //true 深度监听
    }
  },
  methods: {
    onDelete(element, index) {
      this.active = index - 1;
      this.drawingList.splice(index, 1);
      this.activeFormItem = index > 0 ? this.drawingList[index - 1] : {};
    },
    onCopy(element, index) {
      let data = JSON.parse(JSON.stringify(element));
      data.model = data.type + "_" + new Date().getTime();
      this.active = index + 1;
      this.drawingList.splice(index + 1, 0, data);
      this.activeFormItem = data;
    },
    onEmpty() {
      this.drawingList = [];
      this.activeFormItem = {};
      this.active = -1;
    },
    onFormItem(data, index) {
      this.active = index;
      this.activeFormItem = data;
    },
    oNcode() {
      const html = vueTemplate(makeUpHtml(this.drawingList, this.formConfig));
      const script = vueScript(makeUpJs(this.drawingList, this.formConfig));
      const css = cssStyle(makeUpCss(this.drawingList));

      this.vueCode = beautifier.html(html + script + css, beautifierConf.html);
      this.dialogVisible = true;
    },
    onStart(evt) {
      this.active = evt.oldDraggableIndex;
    },
    addComponent(item) {
      let data = JSON.parse(JSON.stringify(item));
      data.model = data.type + "_" + new Date().getTime();
      this.activeFormItem = data;
      if (this.active === -1) {
        this.active = 0;
        this.drawingList.push(data);
      } else {
        this.drawingList.splice(this.active + 1, 0, data);
        this.active += 1;
      }
    },
    onEnd(obj) {
      this.active = obj.newIndex;
    },
    cloneComponent(origin) {
      let data = JSON.parse(JSON.stringify(origin));
      data.model = data.type + "_" + new Date().getTime();
      this.activeFormItem = data;
      return data;
    }
  }
};
</script>

<style lang="scss">
.bg_box {
  background-color: rgb(255, 255, 255);
  .header {
    width: 100%;
    height: 56px;
    background: #6A66F6;
    color: #fff;
    line-height: 56px;
    font-size: 18px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: space-around;
    .topTbas {
      cursor: pointer;
    }
  }
  .content {
    margin-top: 6px;
    height: calc(100% - 62px);
    display: flex;
    overflow: hidden;
    .left {
      height: 100%;
      overflow: auto;
      box-shadow: 0 0 1px 1px #ccc;
      width: 270px;
      display: block;
      box-sizing: border-box;
      .left-scrollbar {
        height: 100%;
        overflow: hidden;
      }
    }
    .section {
      max-width: calc(100% - 540px);
      flex: 1;
      margin: 0 8px 0;
      box-shadow: 0 0 1px 1px #ccc;
      .center-scrollbar {
        height: 100%;
        overflow: hidden;
        border-left: 1px solid #f1e8e8;
        border-right: 1px solid #f1e8e8;
        box-sizing: border-box;
      }
    }
    .right {
      height: 100%;
      overflow: auto;
      box-shadow: 0 0 1px 1px #ccc;
      width: 270px;
      display: block;
      box-sizing: border-box;
    }
  }
}
.drawing {
  // pointer-events: none;
  cursor: pointer;
  position: relative;
  box-sizing: border-box;
  padding: 15px 100px;
  overflow: hidden;
  transition: all 0.3s;
  min-height: 36px;
  &:hover {
    background: #6A66F620;
  }
  // 选择时 start
  &::before {
    content: "";
    height: 5px;
    width: 100%;
    background: #6A66F6;
    position: absolute;
    top: 0;
    right: -100%;
    transition: all 0.3s;
  }

  &.active {
    &::before {
      right: 0;
    }
    background: #6A66F620;
    outline-offset: 0;
  }

  // 选择时 end
  .drawing_masking {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;

    &::before {
      content: "";
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      z-index: 888;
    }
  }

  .rightTop {
    position: absolute;
    right: 0;
    top: 0;
    display: none;
    z-index: 888;
    &.active {
      display: inline-block;
    }
    .copy {
      width: 30px;
      height: 30px;
      line-height: 30px;
      text-align: center;
      background: #6A66F6;
      transition: all 0.3s;
      border-radius: 0 0 0 8px;
      color: #fff;
      cursor: pointer;
      display: inline-block;
    }
    .delete {
      display: inline-block;
      width: 30px;
      height: 30px;
      line-height: 30px;
      text-align: center;
      transition: all 0.3s;
      background: #6A66F6;
      color: #fff;
      cursor: pointer;
    }
  }
  // .show-key-box {
  //   // 显示key
  //   position: absolute;
  //   bottom: 2px;
  //   right: 5px;
  //   font-size: 14px;

  //   color: #6A66F6;
  // }
}
.components-draggable {
  padding: 5px;
  list-style: none;
  display: flex;
  margin-bottom: 0;
  flex-wrap: wrap;
  .components-item {
    transition: transform 0ms !important;
    border-radius: 0;
    border: 0;
    box-shadow: 1px 0 0 0 #ccc, 0 1px 0 0 #ccc, 1px 1px 0 0 #ccc,
      1px 0 0 0 #ccc inset, 0 1px 0 0 #ccc inset;
    padding: 8px 12px;
    transition: all 0.3s;
    width: calc(50% - 6px);
    margin: 2.7px;
    height: 36px;
    line-height: 20px;
    cursor: move;
    border: 1px solid transparent;
    border-radius: 3px;
    transition: all 0.3s;

    &:hover {
      color: #6A66F6;
      border: 1px solid #6A66F6;
      position: relative;
      z-index: 1;
      box-shadow: 0 2px 6px #6A66F6;
    }
  }
}

.empty-info {
  position: absolute;
  top: 46%;
  left: 0;
  right: 0;
  text-align: center;
  font-size: 18px;
  color: #6A66F6;
  letter-spacing: 4px;
}
.form {
  height: 100%;
}
.drawing-board {
  height: 100%;
  position: relative;

  .sortable-ghost {
    position: relative;
    display: block;
    overflow: hidden;
    transition: all 0.3s;
    &::before {
      content: "";
      position: absolute;
      top: 0;
      right: -100%;
      transition: all 0.3s;
    }
  }
  .components-item.sortable-ghost {
    width: 100%;
    height: 60px;
    border-top: 5px solid #6A66F6;
    transition: all 0.3s;
  }

  .el-form-item {
    margin-bottom: 15px;
  }
}

.el-scrollbar__view {
  height: 100%;
}

.action-bar {
  position: relative;
  height: 42px;
  text-align: right;
  padding: 0 15px;
  box-sizing: border-box;
  border: 1px solid #f1e8e8;
  border-top: none;
  border-left: none;
  .delete-btn {
    color: #6A66F6;
  }
}
.CodeMirror {
  height: 800px;
}
</style>
